<template>
  <div class="v-table-picker">
    <div class="v-table-picker__placeholder" @click="visible=true">{{ getText }}</div>
    <el-dialog
      custom-class="v-table-picker__dialog"
      :visible.sync="visible"
      :title="title"
      width="500px"
      append-to-body
      @close="visible=false"
    >
      <el-input
        v-model="keyword"
        placeholder="请输入"
        style="width: 100%;"
        @keyup.enter.native="handleFetch"
      />
      <el-table
        ref="tableRef"
        :data="getOptions"
        border
        style="width: 100%;"
        highlight-current-row
        @current-change="handleCurrentChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column type="index" width="60" label="序号" />
        <el-table-column
          v-for="item in columns"
          :key="item.prop"
          :prop="item.prop"
          :label="item.label"
        />
      </el-table>
      <pagination
        :page.sync="page.page"
        :limit.sync="page.size"
        :total="total"
        layout="prev, pager, next"
        @pagination="handleFetch"
      />
    </el-dialog>
  </div>
</template>

<script>
import request from '@/utils/request'
import Pagination from '@/components/Pagination'

export default {
  name: 'VTablePicker',
  inheritAttrs: false,
  components: {
    Pagination
  },
  model: {
    prop: 'value',
    event: 'input'
  },
  props: {
    value: null,
    title: {
      type: String,
      default: '商品选择'
    },
    url: String,
    columns: Array,
    params: null,
    labelField: {
      type: String,
      default: 'label'
    },
    valueField: {
      type: String,
      default: 'value'
    },
    isObject: Boolean,
    link: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      visible: false,
      page: {
        page: 1,
        size: 10
      },
      keyword: '',
      total: 0,
      tableData: []
    }
  },
  computed: {
    getOptions() {
      const {
        labelField,
        valueField,
        numberToString,
        tableData,
        link
      } = this

      return tableData.reduce((prev, next) => {
        if (next) {
          const value = next[valueField]
          if (!link.includes(value)) {
            prev.push({
              ...next,
              label: next[labelField],
              value: numberToString ? `${value}` : value
            })
          }
        }
        return prev
      }, [])
    },
    getText() {
      const {
        labelField,
        valueField,
        tableData,
        value
      } = this
      const val = tableData.find(item => item[valueField] === value)
      return (val && val[labelField]) || '请选择'
    }
  },
  watch: {
    params: {
      handler() {
        this.handleFetch()
      },
      deep: true
    }
  },
  created() {
    this.handleFetch()
  },
  methods: {
    handleFetch() {
      const config = {
        url: this.url,
        methods: 'get',
        params: {
          ...this.params,
          ...this.page,
          keyword: this.keyword
        }
      }
      request(config).then((res) => {
        this.tableData = res.content || res.data.content
        this.total = res.totalElements || res.data.totalElements
        this.emitChange()
      })
    },
    setCurrent(row) {
      this.$refs.tableRef.setCurrentRow(row)
    },
    handleCurrentChange(val) {
      this.$refs.tableRef.clearSelection()
      this.$refs.tableRef.toggleRowSelection(val)
      const value = val[this.valueField]
      this.$emit('input', value)
      const data = this.isObject ? this.getOptions.find(item => item.value === val) : val
      this.$emit('change', data)
      this.$nextTick(() => {
        this.visible = false
      })
    },
    emitChange() {
      this.$emit('options-change', this.getOptions)
    }
  }
}
</script>

<style lang="scss">
.v-table-picker {
  .v-table-picker__placeholder {
    cursor: pointer;
  }
}

.v-table-picker__dialog {
  .el-dialog__body {
    padding-bottom: 5px;
  }

  .el-input {
    margin-bottom: 8px;
  }

  .pagination-container {
    padding: 0;
    margin: 10px;
    text-align: center;
  }
}
</style>
